package ua.flatmap.processor.slando;

import com.flatsmap.dto.PoiDTO;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version;
import org.springframework.util.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import ua.flatmap.processor.XMLReader;
import ua.flatmap.util.AddressToCoordinatesRetriever;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.IOException;
import java.io.StringReader;

/**
 * Created by IntelliJ IDEA.
 * User: Kostya
 * Date: 14.07.11
 */
public class SlandoXMLReader extends XMLReader {
    public void execute(String result) {
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            InputSource is = new InputSource(new StringReader(result));
            Document doc = db.parse(is);
            doc.getDocumentElement().normalize();
            NodeList appartments = doc.getElementsByTagName("appartment");

            for (int s = 0; s < appartments.getLength(); s++) {

                Node fstNode = appartments.item(s);

                if (fstNode.getNodeType() == Node.ELEMENT_NODE) {
                    PoiDTO newPOI = new PoiDTO();
                    Element fstElmnt = (Element) fstNode;

                    String priceStr = getNodeValue(fstElmnt, "price");
                    priceStr = StringUtils.replace(priceStr, "грн.", "");
                    priceStr = StringUtils.replace(priceStr, " ", "");
                    Double price = Double.parseDouble(priceStr);
                    newPOI.setPrice(price);

                    String roomNumberString = getNodeValue(fstElmnt, "room");
                    roomNumberString = roomNumberString.substring(0, 1);
                    Integer roomNumber = Integer.parseInt(roomNumberString);
                    newPOI.setRoomNumber(roomNumber);


                    NodeList contactsElmntLst = fstElmnt.getElementsByTagName("contacts");
                    Element contactsElmnt = (Element) contactsElmntLst.item(0);
                    NodeList contacts = contactsElmnt.getChildNodes();
                    if (contacts.item(0) != null) {
                        newPOI.setContacts(contacts.item(0).getNodeValue());
                    }
                    String descValue = getNodeValue(fstElmnt, "description");

                    newPOI.setDescription(descValue);
                    String street;
                    street = calculateStreet(descValue);


                    newPOI.setStreet(street);
                    Double[] coordinates = AddressToCoordinatesRetriever.getCoordinates(street);
                    newPOI.setLng(coordinates[0]);
                    newPOI.setLat(coordinates[1]);
                    poiService.save(newPOI);
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private String calculateStreet(String description) {
        RAMDirectory idx = new RAMDirectory();
        try {
            IndexWriter writer = new IndexWriter(idx, new StandardAnalyzer(Version.LUCENE_32),
                    IndexWriter.MaxFieldLength.LIMITED);
            writer.addDocument(createDocument(description));
            writer.optimize();
            writer.close();
            IndexSearcher searcher = new IndexSearcher(idx);

            for (String street : getStreets().keySet()) {
                Float result = search(searcher, street);
                getStreets().put(street, result);
            }

            searcher.close();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        } catch (ParseException pe) {
            pe.printStackTrace();
        }

        String street = null;
        float maxHit = 0;
        for (String str : getStreets().keySet()) {
            if (getStreets().get(str) > maxHit) {
                maxHit = getStreets().get(str);
                street = str;
            }
        }
        return street;

    }
}
